home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / bfd / bout.c < prev    next >
C/C++ Source or Header  |  1992-09-11  |  23KB  |  756 lines

  1. /* BFD back-end for Intel 960 b.out binaries.
  2.    Copyright (C) 1990-1991 Free Software Foundation, Inc.
  3.    Written by Cygnus Support.
  4.  
  5. This file is part of BFD, the Binary File Descriptor library.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* $Id: bout.c,v 1.17 1991/10/16 18:40:24 gnu Exp $ */
  22.  
  23. #include "bfd.h"
  24. #include "sysdep.h"
  25. #include "libbfd.h"
  26.  
  27. #include "bout.h"
  28.  
  29. #include "stab.gnu.h"
  30. #include "libaout.h"        /* BFD a.out internal data structures */
  31.  
  32. PROTO (static boolean, b_out_squirt_out_relocs,(bfd *abfd, asection *section));
  33. PROTO (static bfd_target *, b_out_callback, (bfd *));
  34.  
  35. PROTO (boolean, aout_32_slurp_symbol_table, (bfd *abfd));
  36. PROTO (void , aout_32_write_syms, ());
  37.  
  38. /* Swaps the information in an executable header taken from a raw byte
  39.    stream memory image, into the internal exec_header structure.  */
  40.  
  41. PROTO(void, bout_swap_exec_header_in,
  42.       (bfd *abfd,
  43.       struct external_exec *raw_bytes,
  44.       struct internal_exec *execp));
  45.      
  46. void
  47. DEFUN(bout_swap_exec_header_in,(abfd, raw_bytes, execp),
  48.       bfd *abfd AND
  49.       struct external_exec *raw_bytes AND
  50.       struct internal_exec *execp)
  51. {
  52.   struct external_exec *bytes = (struct external_exec *)raw_bytes;
  53.  
  54.   /* Now fill in fields in the execp, from the bytes in the raw data.  */
  55.   execp->a_info   = bfd_h_get_32 (abfd, bytes->e_info);
  56.   execp->a_text   = GET_WORD (abfd, bytes->e_text);
  57.   execp->a_data   = GET_WORD (abfd, bytes->e_data);
  58.   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
  59.   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
  60.   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
  61.   execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
  62.   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
  63.   execp->a_tload  = GET_WORD (abfd, bytes->e_tload);
  64.   execp->a_dload  = GET_WORD (abfd, bytes->e_dload);
  65.   execp->a_talign = bytes->e_talign[0];
  66.   execp->a_dalign = bytes->e_dalign[0];
  67.   execp->a_balign = bytes->e_balign[0];
  68. }
  69.  
  70. /* Swaps the information in an internal exec header structure into the
  71.    supplied buffer ready for writing to disk.  */
  72.  
  73. PROTO(void, bout_swap_exec_header_out,
  74.       (bfd *abfd,
  75.        struct internal_exec *execp,
  76.        struct external_exec *raw_bytes));
  77. void
  78. DEFUN(bout_swap_exec_header_out,(abfd, execp, raw_bytes),
  79.      bfd *abfd AND
  80.      struct internal_exec *execp AND 
  81.      struct external_exec *raw_bytes)
  82. {
  83.   struct external_exec *bytes = (struct external_exec *)raw_bytes;
  84.  
  85.   /* Now fill in fields in the raw data, from the fields in the exec struct. */
  86.   bfd_h_put_32 (abfd, execp->a_info  , bytes->e_info);
  87.   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
  88.   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
  89.   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
  90.   PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
  91.   PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
  92.   PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
  93.   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
  94.   PUT_WORD (abfd, execp->a_tload , bytes->e_tload);
  95.   PUT_WORD (abfd, execp->a_dload , bytes->e_dload);
  96.   bytes->e_talign[0] = execp->a_talign;
  97.   bytes->e_dalign[0] = execp->a_dalign;
  98.   bytes->e_balign[0] = execp->a_balign;
  99.   bytes->e_unused[0] = 0;        /* Clean structs are godly structs */
  100. }
  101.  
  102.  
  103. static bfd_target *
  104. b_out_object_p (abfd)
  105.      bfd *abfd;
  106. {
  107.   struct internal_exec anexec;
  108.   struct external_exec exec_bytes;
  109.  
  110.   if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
  111.       != EXEC_BYTES_SIZE) {
  112.     bfd_error = wrong_format;
  113.     return 0;
  114.   }
  115.  
  116.   anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
  117.  
  118.   if (N_BADMAG (anexec)) {
  119.     bfd_error = wrong_format;
  120.     return 0;
  121.   }
  122.  
  123.   bout_swap_exec_header_in (abfd, &exec_bytes, &anexec);
  124.   return aout_32_some_aout_object_p (abfd, &anexec, b_out_callback);
  125. }
  126.  
  127.  
  128. /* Finish up the opening of a b.out file for reading.  Fill in all the
  129.    fields that are not handled by common code.  */
  130.  
  131. static bfd_target *
  132. b_out_callback (abfd)
  133.      bfd *abfd;
  134. {
  135.   struct internal_exec *execp = exec_hdr (abfd);
  136.   unsigned long bss_start;
  137.  
  138.   /* Architecture and machine type */
  139.   bfd_set_arch_mach(abfd, 
  140.             bfd_arch_i960, /* B.out only used on i960 */
  141.             bfd_mach_i960_core /* Default */
  142.             );
  143.  
  144.   /* The positions of the string table and symbol table.  */
  145.   obj_str_filepos (abfd) = N_STROFF (*execp);
  146.   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
  147.  
  148.   /* The alignments of the sections */
  149.   obj_textsec (abfd)->alignment_power = execp->a_talign;
  150.   obj_datasec (abfd)->alignment_power = execp->a_dalign;
  151.   obj_bsssec  (abfd)->alignment_power = execp->a_balign;
  152.  
  153.   /* The starting addresses of the sections.  */
  154.   obj_textsec (abfd)->vma = execp->a_tload;
  155.   obj_datasec (abfd)->vma = execp->a_dload;
  156.   bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */
  157.   obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign);
  158.  
  159.   /* The file positions of the sections */
  160.   obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
  161.   obj_datasec (abfd)->filepos = N_DATOFF(*execp);
  162.  
  163.   /* The file positions of the relocation info */
  164.   obj_textsec (abfd)->rel_filepos = N_TROFF(*execp);
  165.   obj_datasec (abfd)->rel_filepos =  N_DROFF(*execp);
  166.  
  167.   adata(abfd)->page_size = 1; /* Not applicable. */
  168.   adata(abfd)->segment_size = 1; /* Not applicable. */
  169.   adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
  170.  
  171.   return abfd->xvec;
  172. }
  173.  
  174. struct container {
  175.     struct aoutdata a;
  176.     struct internal_exec e;
  177. };
  178.  
  179. static boolean
  180. b_out_mkobject (abfd)
  181.      bfd *abfd;
  182. {
  183.   struct container *rawptr;
  184.  
  185.   rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
  186.   if (rawptr == NULL) {
  187.     bfd_error = no_memory;
  188.     return false;
  189.   }
  190.  
  191.   set_tdata (abfd, &rawptr->a);
  192.   exec_hdr (abfd) = &rawptr->e;
  193.  
  194.   /* For simplicity's sake we just make all the sections right here. */
  195.   obj_textsec (abfd) = (asection *)NULL;
  196.   obj_datasec (abfd) = (asection *)NULL;
  197.   obj_bsssec (abfd) = (asection *)NULL;
  198.  
  199.   bfd_make_section (abfd, ".text");
  200.   bfd_make_section (abfd, ".data");
  201.   bfd_make_section (abfd, ".bss");
  202.  
  203.   return true;
  204. }
  205.  
  206. static boolean
  207. b_out_write_object_contents (abfd)
  208.      bfd *abfd;
  209. {
  210.   struct external_exec swapped_hdr;
  211.  
  212.   exec_hdr (abfd)->a_info = BMAGIC;
  213.  
  214.   exec_hdr (abfd)->a_text = obj_textsec (abfd)->size;
  215.   exec_hdr (abfd)->a_data = obj_datasec (abfd)->size;
  216.   exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->size;
  217.   exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
  218.   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
  219.   exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) *
  220.                                sizeof (struct relocation_info));
  221.   exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) *
  222.                                sizeof (struct relocation_info));
  223.  
  224.   exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power;
  225.   exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power;
  226.   exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power;
  227.  
  228.   exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma;
  229.   exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma;
  230.  
  231.   bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
  232.  
  233.   bfd_seek (abfd, 0L, SEEK_SET);
  234.   bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd);
  235.  
  236.   /* Now write out reloc info, followed by syms and strings */
  237.   if (bfd_get_symcount (abfd) != 0) 
  238.     {
  239.       bfd_seek (abfd,
  240.         (long)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET);
  241.  
  242.       aout_32_write_syms (abfd);
  243.  
  244.       bfd_seek (abfd,    (long)(N_TROFF(*exec_hdr(abfd))), SEEK_SET);
  245.  
  246.       if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
  247.       bfd_seek (abfd, (long)(N_DROFF(*exec_hdr(abfd))), SEEK_SET);
  248.  
  249.       if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
  250.     }
  251.   return true;
  252. }
  253.  
  254. /** Some reloc hackery */
  255.  
  256. #define CALLS     0x66003800    /* Template for 'calls' instruction    */
  257. #define BAL     0x0b000000    /* Template for 'bal' instruction    */
  258. #define BAL_MASK 0x00ffffff
  259.  
  260. static bfd_reloc_status_type 
  261. callj_callback(abfd, reloc_entry, symbol_in, data, input_section)
  262. bfd *abfd;
  263. arelent *reloc_entry;
  264. asymbol *symbol_in;
  265. unsigned char *data;
  266. asection *input_section;
  267. {
  268.   int  word = bfd_get_32(abfd, data+reloc_entry->address);
  269.   aout_symbol_type  *symbol = aout_symbol(symbol_in);
  270.  
  271.   if (IS_OTHER(symbol->other)) {
  272.     /* Call to a system procedure - replace code with system
  273.        procedure number 
  274.        */
  275.  
  276.     word = CALLS | (symbol->other - 1);
  277.     bfd_put_32(abfd, word,  data+reloc_entry->address); /* replace */
  278.     return bfd_reloc_ok;
  279.   }
  280.     
  281.   if (IS_CALLNAME(symbol->other)) {
  282.     aout_symbol_type *balsym = symbol+1;
  283.     /* The next symbol should be an N_BALNAME */
  284.     BFD_ASSERT(IS_BALNAME(balsym->other));
  285.  
  286.     /* We are calling a leaf - so replace the call instruction
  287.        with a bal */
  288.   
  289.     word = BAL |
  290.       (((word & BAL_MASK) +
  291.      balsym->symbol.section->output_offset +
  292.      balsym->symbol.section->output_section->vma+
  293.     balsym->symbol.value + reloc_entry->addend - 
  294.     ( input_section->output_section->vma + input_section->output_offset))
  295.        & BAL_MASK);
  296.  
  297.     bfd_put_32(abfd, word,  data+reloc_entry->address); /* replace */
  298.     return bfd_reloc_ok;
  299.   }
  300.   return bfd_reloc_continue;
  301.  
  302. }
  303. /* type rshift size  bitsize      pcrel    bitpos  absolute overflow check*/
  304.  
  305.  
  306. static reloc_howto_type howto_reloc_callj =
  307. HOWTO( 3, 0, 2, 24, true, 0, true, true, callj_callback,"callj", true, 0x00ffffff, 0x00ffffff,false);
  308. static  reloc_howto_type howto_reloc_abs32 =
  309. HOWTO(1, 0, 2, 32, false, 0, true, true,0,"abs32", true, 0xffffffff,0xffffffff,false);
  310. static reloc_howto_type howto_reloc_pcrel24 =
  311. HOWTO(2, 0, 2, 24, true, 0, true, true,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false);
  312.  
  313. /* Allocate enough room for all the reloc entries, plus pointers to them all */
  314.  
  315. static boolean
  316. b_out_slurp_reloc_table (abfd, asect, symbols)
  317.      bfd *abfd;
  318.      sec_ptr asect;
  319.      asymbol **symbols;
  320. {
  321.   unsigned int count;
  322.   size_t  reloc_size;
  323.   struct relocation_info *relocs;
  324.   arelent *reloc_cache;
  325.  
  326.   if (asect->relocation) return true;
  327.   if (!aout_32_slurp_symbol_table (abfd)) return false;
  328.  
  329.   if (asect == obj_datasec (abfd)) {
  330.     reloc_size = exec_hdr(abfd)->a_drsize;
  331.     goto doit;
  332.   }
  333.  
  334.   if (asect == obj_textsec (abfd)) {
  335.     reloc_size = exec_hdr(abfd)->a_trsize;
  336.     goto doit;
  337.   }
  338.  
  339.   bfd_error = invalid_operation;
  340.   return false;
  341.  
  342.  doit:
  343.   bfd_seek (abfd, (long)(asect->rel_filepos), SEEK_SET);
  344.   count = reloc_size / sizeof (struct relocation_info);
  345.  
  346.   relocs = (struct relocation_info *) malloc (reloc_size);
  347.   if (!relocs) {
  348.     bfd_error = no_memory;
  349.     return false;
  350.   }
  351.   reloc_cache = (arelent *) malloc ((count+1) * sizeof (arelent));
  352.   if (!reloc_cache) {
  353.     free ((char*)relocs);
  354.     bfd_error = no_memory;
  355.     return false;
  356.   }
  357.  
  358.   if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) {
  359.     bfd_error = system_call_error;
  360.     free (reloc_cache);
  361.     free (relocs);
  362.     return false;
  363.   }
  364.  
  365.   {
  366.     register struct relocation_info *rptr = relocs;
  367.     unsigned int counter = 0;
  368.     arelent *cache_ptr = reloc_cache;
  369.     int extern_mask, pcrel_mask, callj_mask;
  370.   
  371.     if (abfd->xvec->header_byteorder_big_p) {
  372.       /* Big-endian bit field allocation order */
  373.       pcrel_mask  = 0x80;
  374.       extern_mask = 0x10;
  375.       callj_mask  = 0x02;
  376.     } else {
  377.       /* Little-endian bit field allocation order */
  378.       pcrel_mask  = 0x01;
  379.       extern_mask = 0x08;
  380.       callj_mask  = 0x40;
  381.     }
  382.  
  383.     for (; counter < count; counter++, rptr++, cache_ptr++) 
  384.       {
  385.     unsigned char *raw = (unsigned char *)rptr;
  386.     unsigned int symnum;
  387.     cache_ptr->address = bfd_h_get_32 (abfd, raw + 0);
  388.      if (abfd->xvec->header_byteorder_big_p) {
  389.       symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
  390.      } else {
  391.       symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];
  392.     }
  393.  
  394.     if (raw[7] & extern_mask) {
  395.       /* If this is set then the r_index is a index into the symbol table;
  396.        * if the bit is not set then r_index contains a section map.
  397.        * We either fill in the sym entry with a pointer to the symbol,
  398.        * or point to the correct section
  399.        */
  400.       cache_ptr->sym_ptr_ptr = symbols + symnum;
  401.       cache_ptr->addend = 0;
  402.       cache_ptr->section = (asection*)NULL;
  403.     } else {
  404.       /* In a.out symbols are relative to the beginning of the
  405.        * file rather than sections ?
  406.        * (look in translate_from_native_sym_flags)
  407.        * The reloc entry addend has added to it the offset into the
  408.        * file of the data, so subtract the base to make the reloc
  409.        * section relative */
  410.       cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
  411.       switch (symnum) {
  412.       case N_TEXT:
  413.       case N_TEXT | N_EXT:
  414.         cache_ptr->section = obj_textsec(abfd);
  415.         cache_ptr->addend = -obj_textsec(abfd)->vma;
  416.         break;
  417.       case N_DATA:
  418.       case N_DATA | N_EXT:
  419.         cache_ptr->section = obj_datasec(abfd);
  420.         cache_ptr->addend = - obj_datasec(abfd)->vma;
  421.         break;
  422.       case N_BSS:
  423.       case N_BSS | N_EXT:
  424.         cache_ptr->section = obj_bsssec(abfd);
  425.         cache_ptr->addend =  - obj_bsssec(abfd)->vma;
  426.         break;
  427.       case N_ABS:
  428.       case N_ABS | N_EXT:
  429.         BFD_ASSERT(0);
  430.         break;
  431.       default:
  432.         BFD_ASSERT(0);
  433.         break;
  434.       }
  435.     
  436.     }
  437.  
  438.      /* The i960 only has a few relocation types:
  439.        abs 32-bit and pcrel 24bit.   Except for callj's!  */
  440.     if (raw[7] & callj_mask)
  441.       cache_ptr->howto = &howto_reloc_callj;
  442.     else if ( raw[7] & pcrel_mask)
  443.       cache_ptr->howto = &howto_reloc_pcrel24;
  444.     else
  445.       cache_ptr->howto = &howto_reloc_abs32;
  446.       }
  447.   }
  448.  
  449.   free (relocs);
  450.   asect->relocation = reloc_cache;
  451.   asect->reloc_count = count;
  452.   return true;
  453. }
  454.  
  455.  
  456. static boolean
  457. b_out_squirt_out_relocs (abfd, section)
  458.      bfd *abfd;
  459.      asection *section;
  460. {
  461.   arelent **generic;
  462.  
  463.   unsigned int count = section->reloc_count;
  464.   struct relocation_info *native, *natptr;
  465.   size_t natsize = count * sizeof (struct relocation_info);
  466.   int extern_mask, pcrel_mask,  len_2, callj_mask;
  467.   if (count == 0) return true;
  468.   generic   = section->orelocation;
  469.   native = ((struct relocation_info *) malloc (natsize));
  470.   if (!native) {
  471.     bfd_error = no_memory;
  472.     return false;
  473.   }
  474.  
  475.    if (abfd->xvec->header_byteorder_big_p) {
  476.        /* Big-endian bit field allocation order */
  477.        pcrel_mask  = 0x80;
  478.        extern_mask = 0x10;
  479.        len_2       = 0x40;
  480.       callj_mask  = 0x02;
  481.    } else {
  482.        /* Little-endian bit field allocation order */
  483.        pcrel_mask  = 0x01;
  484.        extern_mask = 0x08;
  485.        len_2       = 0x04;
  486.       callj_mask  = 0x40;
  487.    }
  488.  
  489.   for (natptr = native; count > 0; --count, ++natptr, ++generic) 
  490.     {
  491.       arelent *g = *generic;
  492.       unsigned char *raw = (unsigned char *)natptr;
  493.       unsigned int symnum;
  494.  
  495.       bfd_h_put_32(abfd, g->address, raw);  
  496.       /* Find a type in the output format which matches the input howto - 
  497.        * at the moment we assume input format == output format FIXME!!
  498.        */
  499.       /* FIXME:  Need callj stuff here, and to check the howto entries to
  500.      be sure they are real for this architecture.  */
  501.       if (g->howto== &howto_reloc_callj) {
  502.     raw[7] = callj_mask + pcrel_mask + len_2;
  503.       }
  504.       else if (g->howto == &howto_reloc_pcrel24) {
  505.     raw[7] = pcrel_mask +len_2;
  506.       }
  507.       else {
  508.     raw[7] = len_2;
  509.       }
  510.       if (g->sym_ptr_ptr != (asymbol **)NULL) 
  511.     {
  512.       /* name clobbered by aout_write_syms to be symbol index*/
  513.       if ((*(g->sym_ptr_ptr))->section) {
  514.         /* replace the section offset into the addent */
  515.         g->addend += (*(g->sym_ptr_ptr))->section->vma ;
  516.       }
  517.       symnum = stoi((*(g->sym_ptr_ptr))->name);
  518.       raw[7] |= extern_mask;
  519.       BFD_ASSERT(g->addend == 0);
  520.     }
  521.       else {
  522.     if (g->section == (asection *)NULL) {
  523.       symnum = N_ABS;
  524.       BFD_ASSERT(0);
  525.     }
  526.     else  if(g->section->output_section == obj_textsec(abfd)) {
  527.       symnum = N_TEXT;
  528.        BFD_ASSERT(g->addend + obj_textsec(abfd)->vma == 0);
  529.     }
  530.     else if (g->section->output_section == obj_datasec(abfd)) {
  531.       symnum  = N_DATA;
  532.        BFD_ASSERT(g->addend + obj_datasec(abfd)->vma == 0);
  533.     }
  534.     else if (g->section->output_section == obj_bsssec(abfd)) {
  535.       symnum = N_BSS;
  536.        BFD_ASSERT(g->addend + obj_bsssec(abfd)->vma == 0);
  537.     }
  538.     else {
  539.       BFD_ASSERT(0);
  540.       symnum = N_ABS;
  541.     }
  542.       }
  543.       if (abfd->xvec->header_byteorder_big_p) {
  544.     raw[4] = (unsigned char) (symnum >> 16);
  545.     raw[5] = (unsigned char) (symnum >>  8);
  546.     raw[6] = (unsigned char) (symnum      );
  547.       } else {
  548.     raw[6] = (unsigned char) (symnum >> 16);
  549.     raw[5] = (unsigned char) (symnum >>  8);
  550.     raw[4] = (unsigned char) (symnum      );
  551.       }  
  552.     }
  553.  
  554.   if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
  555.     free((PTR)native);
  556.     return false;
  557.   }
  558.   free ((PTR)native);
  559.  
  560.   return true;
  561. }
  562.  
  563. /* This is stupid.  This function should be a boolean predicate */
  564. static unsigned int
  565. b_out_canonicalize_reloc (abfd, section, relptr, symbols)
  566.      bfd *abfd;
  567.      sec_ptr section;
  568.      arelent **relptr;
  569.      asymbol **symbols;
  570. {
  571.   arelent *tblptr = section->relocation;
  572.   unsigned int count = 0;
  573.  
  574.  if (!(tblptr || b_out_slurp_reloc_table (abfd, section, symbols))) return 0;
  575.   tblptr = section->relocation;
  576.  if (!tblptr) return 0;
  577.  
  578.   for (; count++ < section->reloc_count;)
  579.     *relptr++ = tblptr++;
  580.  
  581.   *relptr = 0;
  582.  
  583.   return section->reloc_count;
  584. }
  585.  
  586. static unsigned int
  587. b_out_get_reloc_upper_bound (abfd, asect)
  588.      bfd *abfd;
  589.      sec_ptr asect;
  590. {
  591.   if (bfd_get_format (abfd) != bfd_object) {
  592.     bfd_error = invalid_operation;
  593.     return 0;
  594.   }
  595.  
  596.   if (asect == obj_datasec (abfd))
  597.     return (sizeof (arelent *) *
  598.         ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info))
  599.          +1));
  600.  
  601.   if (asect == obj_textsec (abfd))
  602.     return (sizeof (arelent *) *
  603.         ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info))
  604.          +1));
  605.  
  606.   bfd_error = invalid_operation;
  607.   return 0;
  608. }
  609.  
  610. static boolean
  611. b_out_set_section_contents (abfd, section, location, offset, count)
  612.      bfd *abfd;
  613.      sec_ptr section;
  614.      unsigned char *location;
  615.      file_ptr offset;
  616.       int count;
  617. {
  618.   if (abfd->output_has_begun == false) { /* set by bfd.c handler */
  619.     if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL) /*||
  620.         (obj_textsec (abfd)->size == 0) || (obj_datasec (abfd)->size == 0)*/) {
  621.       bfd_error = invalid_operation;
  622.       return false;
  623.     }
  624.  
  625.     obj_textsec (abfd)->filepos = sizeof(struct internal_exec);
  626.     obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos 
  627.                                 +  obj_textsec (abfd)->size;
  628.  
  629.   }
  630.   /* regardless, once we know what we're doing, we might as well get going */
  631.   bfd_seek (abfd, section->filepos + offset, SEEK_SET);
  632.  
  633.   if (count != 0) {
  634.     return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false;
  635.   }
  636.   return false;
  637. }
  638.  
  639. static boolean
  640. b_out_set_arch_mach (abfd, arch, machine)
  641.      bfd *abfd;
  642.      enum bfd_architecture arch;
  643.      unsigned long machine;
  644. {
  645.   bfd_default_set_arch_mach(abfd, arch, machine);
  646.  
  647.   if (arch == bfd_arch_unknown)    /* Unknown machine arch is OK */
  648.     return true;
  649.   if (arch == bfd_arch_i960)    /* i960 default is OK */
  650.     switch (machine) {
  651.     case bfd_mach_i960_core:
  652.     case bfd_mach_i960_kb_sb:
  653.     case bfd_mach_i960_mc:
  654.     case bfd_mach_i960_xa:
  655.     case bfd_mach_i960_ca:
  656.     case bfd_mach_i960_ka_sa:
  657.     case 0:
  658.       return true;
  659.     default:
  660.       return false;
  661.     }
  662.  
  663.   return false;
  664. }
  665.  
  666. static int 
  667. DEFUN(b_out_sizeof_headers,(ignore_abfd, ignore),
  668.       bfd *ignore_abfd AND
  669.       boolean ignore)
  670. {
  671.   return sizeof(struct internal_exec);
  672. }
  673.  
  674.  
  675.  
  676.  
  677. /* Build the transfer vectors for Big and Little-Endian B.OUT files.  */
  678.  
  679. /* We don't have core files.  */
  680. #define    aout_32_core_file_failing_command _bfd_dummy_core_file_failing_command
  681. #define    aout_32_core_file_failing_signal _bfd_dummy_core_file_failing_signal
  682. #define    aout_32_core_file_matches_executable_p    \
  683.                 _bfd_dummy_core_file_matches_executable_p
  684.  
  685. /* We use BSD-Unix generic archive files.  */
  686. #define    aout_32_openr_next_archived_file    bfd_generic_openr_next_archived_file
  687. #define    aout_32_generic_stat_arch_elt    bfd_generic_stat_arch_elt
  688. #define    aout_32_slurp_armap        bfd_slurp_bsd_armap
  689. #define    aout_32_slurp_extended_name_table    bfd_true
  690. #define    aout_32_write_armap        bsd_write_armap
  691. #define    aout_32_truncate_arname        bfd_bsd_truncate_arname
  692.  
  693. /* We override these routines from the usual a.out file routines.  */
  694. #define    aout_32_canonicalize_reloc    b_out_canonicalize_reloc
  695. #define    aout_32_get_reloc_upper_bound    b_out_get_reloc_upper_bound
  696. #define    aout_32_set_section_contents    b_out_set_section_contents
  697. #define    aout_32_set_arch_mach        b_out_set_arch_mach
  698. #define    aout_32_sizeof_headers        b_out_sizeof_headers
  699.  
  700. #define aout_32_bfd_debug_info_start        bfd_void
  701. #define aout_32_bfd_debug_info_end        bfd_void
  702. #define aout_32_bfd_debug_info_accumulate    (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
  703.  
  704.  
  705. bfd_target b_out_vec_big_host =
  706. {
  707.   "b.out.big",            /* name */
  708.   bfd_target_aout_flavour,
  709.   false,            /* data byte order is little */
  710.   true,                /* hdr byte order is big */
  711.   (HAS_RELOC | EXEC_P |        /* object flags */
  712.    HAS_LINENO | HAS_DEBUG |
  713.    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
  714.   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
  715.   ' ',                /* ar_pad_char */
  716.   16,                /* ar_max_namelen */
  717.      2,                /* minumum alignment power */
  718.  
  719. _do_getl64, _do_putl64,  _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
  720. _do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
  721.     {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
  722.        bfd_generic_archive_p, _bfd_dummy_target},
  723.     {bfd_false, b_out_mkobject,    /* bfd_set_format */
  724.        _bfd_generic_mkarchive, bfd_false},
  725.     {bfd_false, b_out_write_object_contents,    /* bfd_write_contents */
  726.        _bfd_write_archive_contents, bfd_false},
  727.  
  728.   JUMP_TABLE(aout_32)
  729. };
  730.  
  731.  
  732. bfd_target b_out_vec_little_host =
  733. {
  734.   "b.out.little",        /* name */
  735.   bfd_target_aout_flavour,
  736.   false,            /* data byte order is little */
  737.   false,            /* header byte order is little */
  738.   (HAS_RELOC | EXEC_P |        /* object flags */
  739.    HAS_LINENO | HAS_DEBUG |
  740.    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
  741.   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
  742.   ' ',                /* ar_pad_char */
  743.   16,                /* ar_max_namelen */
  744.      2,                /* minum align */
  745. _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
  746. _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */
  747.      
  748.     {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
  749.        bfd_generic_archive_p, _bfd_dummy_target},
  750.     {bfd_false, b_out_mkobject,    /* bfd_set_format */
  751.        _bfd_generic_mkarchive, bfd_false},
  752.     {bfd_false, b_out_write_object_contents,    /* bfd_write_contents */
  753.        _bfd_write_archive_contents, bfd_false},
  754.   JUMP_TABLE(aout_32)
  755. };
  756.